package ru.evga.billboard.graph.preference;

import java.awt.Color;
import java.awt.geom.Rectangle2D;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;


public class GraphSettings
    implements IParamChangeListener
{
    public final IntParam busRowCount = new IntParam("busRowCount", 8, 1, 1024);
    public final IntParam frameCount = new IntParam("frameCount", 1, 1, 1024);
    public final IntParam busColumnCount = new IntParam("busColumnCount", 8, 1, 1024);
    public final IntParam busRowSpace = new IntParam("busRowSpace", 40, 1, 1000);
    public final IntParam busColumnSpace = new IntParam("busColumnSpace", 8, 1, 1000);
    public final IntParam diodeSize = new IntParam("diodeSize", 6, 1, 100);
    public final IntParam busHStrokeWidth = new IntParam("busHStrokeWidth", 20, 0, 1000);
    public final IntParam busVStrokeWidth = new IntParam("busVStrokeWidth", 10, 0, 1000);
    public final ColorParam diodeOnColor = new ColorParam("diodeOnColor", new Color(255, 0, 0));
    public final ColorParam diodeOffColor = new ColorParam("diodeOffColor", new Color(100, 0, 0));
    public final ColorParam diodeSelectColor = new ColorParam("diodeSelectColor", new Color(0, 0,
        255));
    public final ColorParam busHColor = new ColorParam("busHColor", new Color(255, 255, 0));
    public final ColorParam busVColor = new ColorParam("busVColor", new Color(0, 255, 0));
    public final ColorParam backgroundColor = new ColorParam("backgroundColor", new Color(255, 255,
        255));
    public final RectParam background = new RectParam("backgroundPos", new Rectangle2D.Double(0, 0, 600, 300));
    private boolean mayNotify = true;
    private Param<?> [] params = new Param<?>[]
    {
        busRowCount, frameCount, busColumnCount, busRowSpace, busColumnSpace, diodeSize,
        busHStrokeWidth, busHStrokeWidth, busVStrokeWidth, diodeOnColor, diodeOffColor,
        diodeSelectColor, busHColor, busVColor, backgroundColor, background
    };
    private List<IPreferenceChangeListener> changeListeners = new LinkedList<IPreferenceChangeListener>();

    public void addChangeListener(IPreferenceChangeListener listener)
    {
        if (!changeListeners.contains(listener))
        {
            changeListeners.add(listener);
        }
    }

    public void removeChangeListener(IPreferenceChangeListener listener)
    {
        changeListeners.remove(listener);
    }

    public GraphSettings()
    {
        for (Param<?> p : params)
        {
            p.addChangeListener(this);
        }
    }

    @Override
    public void onParamChange(Param param)
    {
        if (mayNotify)
        {
            for (IPreferenceChangeListener listener : changeListeners)
            {
                listener.onPreferenceChanged(this);
            }
        }
    }

    public byte [] getContentAsBytes()
    {
        try
        {
            Properties properties = new Properties();
            for (Param<?> p : params)
            {
                properties.put(p.getKey(), p.toString());
            }
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            properties.store(outputStream, "Saved automatically by billboard program");
            return outputStream.toByteArray();
        }
        catch (IOException e)
        {
            return new byte[0];
        }
    }

    public void setContentFromBytes(byte [] content)
    {
        if (content != null && content.length > 0)
        {
            Properties properties = new Properties();
            try
            {
                properties.load(new ByteArrayInputStream(content));
            }
            catch (IOException e)
            {
                e.printStackTrace();
                return;
            }
            mayNotify = false;
            for (Param<?> p : params)
            {
                p.fromString(properties.getProperty(p.getKey()));
            }
            mayNotify = true;
            onParamChange(null);
        }
    }
}
